<script setup>
import { computed, ref, watch } from 'vue';
import { message } from 'ant-design-vue';
import api from '@/api/index.js'
import IconFont from '@/components/Icon/IconFont.vue';

const emits = defineEmits(['close', 'init', 'reload'])
const props = defineProps({
  curRow: {
    type: Object,
    default: () => ({})
  },
  faMenuSltOpt: {
    type: Array,
    default: () => ([])
  },
})
// 处理按钮类型选择内容
const menuSltOpt = computed(() => {
  function isMenu (list) {
    let result = []
    list.forEach(item => {
      if ([1, 2].includes(item.type)) {
        let children = []
        if (item?.children?.length > 0) {
          children = isMenu(item.children)
        }
        result.push({
          ...item,
          children: children.length > 0 ? children : null
        })
      }
    })
    return result
  }
  return isMenu(props.faMenuSltOpt)
})
// 图标可选项
const iconOpt = ref(window.config.icons)
// 弹窗标题
const title = computed(() => props.curRow.id ? '编辑数据' : '新增数据')
// 表单数据
const formData = ref({
  name: '',
  route: '1',
  type: 1,
  component: '',
  perms: '',
  orderNum: 1
})
// 找到父id
const findPid = (treeData, targetId, level = 0, currentPath = []) => {
  // 遍历当前层的节点
  for (let i = 0; i < treeData.length; i++) {
    // 如果找到目标ID，返回当前层和路径
    if (treeData[i].id === targetId) {
      return { level, path: [...currentPath, treeData[i].id] };
    }
    // 如果存在子节点，递归查找下一层
    if (treeData[i].children && treeData[i].children.length > 0) {
      const result = findPid(treeData[i].children, targetId, level + 1, [...currentPath, treeData[i].id]);
      // 如果找到目标ID，返回结果
      if (result) {
        return result;
      }
    }
  }
  // 如果遍历完所有层都没找到，返回null
  return null;
}
// 按钮类型的父节点id为数组，需要特殊处理
const type3Handler = obj => {
  let result = obj
  if (result.type === 3) {
    let str = JSON.stringify(props.faMenuSltOpt)
    let array = JSON.parse(str)
    let { path } = findPid(array, obj.id)
    path.pop()
    result.parentId = path
  }
  return result
}
// 同步表格数据到表单数据内
watch(() => props.curRow, (val) => {
  // 按钮类型的父节点id为数组，需要特殊处理
  formData.value = { ...formData.value, ...val }
  formData.value = type3Handler(formData.value)
}, { deep: true, immediate: true })
// 是否显示弹窗
const show = ref(false);
// 弹窗显示状态切换时触发
const afterOpenChange = bool => {
  if (!bool) {
    formData.value = {
      name: '',
      route: '1',
      type: 1,
      component: '',
      perms: '',
      orderNum: 1
    }
    emits('close')
  }
};
// 提交按钮loading状态
const submitLoading = ref(false)
// 编辑数据
const emitItem = async (info) => {
  submitLoading.value = true
  let params = { ...formData.value, ...info }
  // 树状组件选中数据为数组，需要处理
  params.parentId = Array.isArray(params.parentId) ? params.parentId[params.parentId.length - 1] : params.parentId
  await api.editMenu(params)
  message.success('编辑成功');
  show.value = false
  setTimeout(() => {
    submitLoading.value = false
  }, 30);
  emits('reload')
}
// 新增数据
const addItem = async (info) => {
  submitLoading.value = true
  let params = { ...formData.value, ...info }
  // 树状组件选中数据为数组，需要处理
  params.parentId = Array.isArray(params.parentId) ? params.parentId[params.parentId.length - 1] : params.parentId
  await api.addMenu(params)
  message.success('新增成功');
  show.value = false
  setTimeout(() => {
    submitLoading.value = false
  }, 30);
  emits('reload')
}
// 表单提交，验证通过了
const onFinish = values => {
  if (formData.value.id) {
    emitItem(values)
  } else {
    addItem(values)
  }
};
// 验证失败
const onFinishFailed = errorInfo => {
  console.log('Failed:', errorInfo);
};
// 打开弹窗
const open = () => {
  show.value = true;
};
// 表单节点
const formRef = ref()
// 提交表单
const submit = () => {
  formRef.value
    .validateFields()
    .then(onFinish)
    .catch(onFinishFailed);
}
defineExpose({ open })
</script>

<template>
  <a-drawer :maskClosable="false" :closable="false" destroyOnClose v-model:open="show" class="custom-class" root-class-name="root-class-name" :title="title"
    placement="right" @after-open-change="afterOpenChange">
    <a-form ref="formRef" :model="formData" layout="vertical" autocomplete="off" @finish="onFinish"
      @finishFailed="onFinishFailed">
      <a-form-item label="名称" name="name" :rules="[{ required: true, message: '请输入名称' }]">
        <a-input v-model:value="formData.name" allowClear />
      </a-form-item>
      <a-form-item label="图标" name="icon">
        <ASelect v-model:value="formData.icon" allowClear>
          <a-select-option v-for="item of iconOpt" :key="item">
            <span v-if="item === 'none'"> 无图标 </span>
            <IconFont :type="item" v-else />
          </a-select-option>
        </ASelect>
      </a-form-item>
      <a-form-item label="类型" name="type" :rules="[{ required: true, message: '请选择类型' }]">
        <a-radio-group v-model:value="formData.type" button-style="solid">
          <a-radio-button :value="1">一级菜单</a-radio-button>
          <a-radio-button :value="2">子菜单</a-radio-button>
          <a-radio-button :value="3">按钮</a-radio-button>
        </a-radio-group>
      </a-form-item>
      <a-form-item label="所属一级菜单" name="parentId" :rules="[{ required: true, message: '请选择一级菜单' }]"
        v-if="[2].includes(formData.type)">
        <ASelect v-model:value="formData.parentId" :options="props.faMenuSltOpt" allowClear
          :fieldNames="{ label: 'name', value: 'id' }" />
      </a-form-item>
      <a-form-item label="所属菜单" name="parentId" :rules="[{ required: true, message: '请选择所属菜单' }]"
        v-if="[3].includes(formData.type)">
        <a-cascader v-model:value="formData.parentId" :options="menuSltOpt" allowClear expand-trigger="hover"
          :fieldNames="{ children: 'children', label: 'name', value: 'id' }" :showSearch="true" />
      </a-form-item>
      <a-form-item label="是否路由" name="route" :rules="[{ required: true, message: '请选择' }]"
        v-if="[1, 2].includes(formData.type)">
        <ASwitch v-model:checked="formData.route" checkedChildren="路由" unCheckedChildren="其他" checkedValue="1"
          unCheckedValue="0" />
      </a-form-item>
      <a-form-item label="组件名称" name="component" :rules="[{ required: true, message: '请输入组件名称' }]"
        v-if="[1, 2].includes(formData.type)">
        <a-input v-model:value="formData.component" />
      </a-form-item>
      <a-form-item label="权限标识" name="perms" :rules="[{ required: true, message: '请输入权限标识' }]" v-else>
        <a-input v-model:value="formData.perms" />
      </a-form-item>
      <a-form-item label="排序" name="orderNum">
        <a-input-number  :min="1" v-model:value="formData.orderNum" />
      </a-form-item>
    </a-form>
    <template #footer>
      <div style="display: flex;gap: 5px;">
        <a-button type="primary" html-type="submit" @click="submit" :loading="submitLoading">提交</a-button>
        <a-button type="primary" ghost @click="show = false">取消</a-button>
      </div>
    </template>
  </a-drawer>
</template>